package vip.sweet.sys.modular.resources.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import vip.sweet.sys.modular.resources.entity.Resources;
import vip.sweet.sys.modular.resources.mapper.ResourcesMapper;
import vip.sweet.sys.modular.resources.params.AddResourcesParams;
import vip.sweet.sys.modular.resources.service.ResourcesService;
import vip.sweet.sys.modular.resources.vo.ResourcesGrantVo;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author tianlianyin
 * @date 2024/11/11
 */
@Service
public class ResourcesServiceImpl extends ServiceImpl<ResourcesMapper, Resources> implements ResourcesService {
    /**
     * 获取资源树
     *
     * @return
     */
    @Override
    public List<Resources> getResourcesTree() {
        List<Resources> resourcesTree = list();
        List<Resources> resourcesVOS = resourcesTree.stream().map(
                resources -> {
                    Resources resourceVO = new Resources();
                    BeanUtils.copyProperties(resources, resourceVO);
                    return resourceVO;
                }
        ).toList();
        return resourcesVOS.stream().filter(resourceVO -> resourceVO.getParentId().equals("top")).peek(menu -> menu.setChildren(getChildrenData(menu, resourcesVOS))).toList();
    }

    @Override
    @Transactional
    public boolean add(AddResourcesParams addResourcesParams) {
        if (Objects.isNull(addResourcesParams))
            return false;
        else {
            Resources resources = BeanUtil.copyProperties(addResourcesParams, Resources.class);
            save(resources);
            return true;
        }
    }

    @Override
    public List<Resources> getRoute() {
        LambdaQueryWrapper<Resources> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Resources::getType, "menu");
        return list(wrapper).stream().map(
                resources -> {
                    Resources resourceVO = new Resources();
                    BeanUtils.copyProperties(resources, resourceVO);
                    return resourceVO;
                }
        ).toList();
    }

    @Override
    public boolean edit(Resources resources) {
        if (Objects.nonNull(resources)) {
            return updateById(resources);
        }
        return false;
    }

    @Override
    public List<ResourcesGrantVo> getGrantedResourcesTree() {
        List<ResourcesGrantVo> resourcesGrantVos = new ArrayList<>();
        LambdaQueryWrapper<Resources> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Resources::getType, "directory");
        List<Resources> resources = list(wrapper);
        if (resources.size() > 0) {
            for (Resources resource : resources) {
                LambdaQueryWrapper<Resources> wrapper1 = new LambdaQueryWrapper<>();
                wrapper1.eq(Resources::getParentId, resource.getId());
                wrapper1.eq(Resources::getType, "menu");
                List<Resources> resources1 = list(wrapper1);
                List<ResourcesGrantVo.ResourcesMenu> resourcesMenus = null;
                if (resources1.size() > 0) {
                    resourcesMenus = new ArrayList<>();
                    for (Resources resource1 : resources1) {
                        LambdaQueryWrapper<Resources> wrapper2 = new LambdaQueryWrapper<>();
                        wrapper2.eq(Resources::getParentId, resource1.getId());
                        wrapper2.eq(Resources::getType, "button");
                        List<Resources> resources2 = list(wrapper2);
                        List<ResourcesGrantVo.ResourcesButton> resourcesButtons = null;
                        if (resources2.size() > 0) {
                            resourcesButtons = new ArrayList<>();
                            for (Resources resource2 : resources2) {
                                ResourcesGrantVo.ResourcesButton.builder().id(resource2.getId()).title(resource2.getName()).build();
                                resourcesButtons.add(ResourcesGrantVo.ResourcesButton.builder().id(resource2.getId()).title(resource2.getName()).build());
                            }
                        }
                        resourcesMenus.add(ResourcesGrantVo.ResourcesMenu.builder()
                                .id(resource1.getId())
                                .title(resource1.getName())
                                .parentId(resource1.getParentId())
                                .parentTitle(resource.getName())
                                .button(resourcesButtons).build());
                    }
                }
                resourcesGrantVos.add(ResourcesGrantVo.builder().id(resource.getId()).name(resource.getName()).menu(resourcesMenus).build());
            }
            return resourcesGrantVos;
        }
        return null;
    }

    //获取孩子（下级目录）的方法，递归实现
    private List<Resources> getChildrenData(Resources root, List<Resources> all) {
        return all.stream().filter(subjectVO ->
                subjectVO.getParentId().equals(root.getId())
        ).peek(subjectVO -> subjectVO.setChildren(getChildrenData(subjectVO, all))).collect(Collectors.toList());
    }
}
